/*
 *所有关于InventoryCount类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*InventoryCountService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.demo.IRepositories;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using VOL.Core.Utilities;
using VOL.Entity.DomainModels;
using VOL.demo.IRepositories;
using VOL.demo.IServices;
using VOL.Core.Extensions.AutofacManager;
using SqlSugar;

namespace VOL.demo.Services
{
    public partial class InventoryCountService
    {
        /// <summary>
        /// 分页查询盘点单
        /// </summary>
        public async Task<WebResponseContent> GetInventoryCountPageListAsync(
            int pageIndex,
            int pageSize,
            string countCode = null,
            string countType = null,
            int? warehouseId = null,
            string countStatus = null,
            DateTime? startTime = null,
            DateTime? endTime = null,
            int? creatorId = null)
        {
            try
            {
                int sqlPageIndex = pageIndex <= 0 ? 0 : pageIndex - 1;
                
                // 联查仓库表和用户表
                var query = repository.DbContext.Queryable<InventoryCount>()
                    // 联查仓库表获取仓库名称
                    .LeftJoin<warehousemodel>((ic, wm) => ic.WarehouseId == wm.Id)
                    // 联查制单人用户表
                    .LeftJoin<Sys_User>((ic, wm, su1) => ic.CreatorId == su1.User_Id)
                    // 联查处理人用户表
                    .LeftJoin<Sys_User>((ic, wm, su1, su2) => ic.HandlerId == su2.User_Id)
                    
                    // 条件过滤
                    .WhereIF(!string.IsNullOrEmpty(countCode), (ic, wm, su1, su2) => ic.CountCode.Contains(countCode))
                    .WhereIF(!string.IsNullOrEmpty(countType), (ic, wm, su1, su2) => ic.CountType == countType)
                    .WhereIF(warehouseId.HasValue, (ic, wm, su1, su2) => ic.WarehouseId == warehouseId)
                    .WhereIF(!string.IsNullOrEmpty(countStatus), (ic, wm, su1, su2) => ic.CountStatus == countStatus)
                    .WhereIF(startTime.HasValue && endTime.HasValue, (ic, wm, su1, su2) => ic.StartTime >= startTime && ic.StartTime <= endTime)
                    .WhereIF(creatorId.HasValue, (ic, wm, su1, su2) => ic.CreatorId == creatorId)
                    
                    // 排序
                    .OrderBy((ic, wm, su1, su2) => SqlFunc.Desc(ic.InventoryCountId))
                    
                    // 选择需要的字段，并添加关联表字段
                    .Select((ic, wm, su1, su2) => new {
                        // 原有盘点单字段
                        ic.InventoryCountId,
                        ic.CountCode,
                        ic.CountType,
                        ic.StartTime,
                        ic.EndTime,
                        ic.WarehouseId,
                        ic.CreatorId,
                        ic.HandlerId,
                        ic.Department,
                        ic.CreateTime,
                        ic.CountStatus,
                        ic.OutStatus,
                        ic.InStatus,
                        ic.Remark,
                        
                        // 新增关联字段
                        WarehouseName = wm.WarehouseName, // 仓库名称
                        CreatorName = su1.UserTrueName,  // 制单人名称
                        HandlerName = su2.UserTrueName   // 处理人名称
                    });

                // 获取总数
                var total = await query.CountAsync();
                // 分页查询
                var data = await query.ToPageListAsync(sqlPageIndex, pageSize);

                return WebResponseContent.Instance.OK("查询成功", new { Data = data, TotalCount = total });
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error($"查询失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 根据盘点单号获取明细列表
        /// </summary>
        public async Task<List<InventoryCountItem>> GetItemsByCountCodeAsync(string countCode)
        {
            var itemService = AutofacContainerModule.GetService<IInventoryCountItemService>();
            return await itemService.GetItemsByCountCodeAsync(countCode);
        }

        /// <summary>
        /// 保存盘点单（主表与明细）
        /// 业务规则：
        /// 1. 前端先保存主表并选择仓库；
        /// 2. 选择仓库后，前端可新增明细（货品来自所选仓库的库存列表）；
        /// 3. 每条明细填写盘点库位、盘点数量、备注，服务端计算盈亏数量与金额以及盘点状态（盘盈/盘亏/无盈亏）；
        /// 4. 点击保存时，服务端在事务中保存主表与明细。
        /// </summary>
        public async Task<WebResponseContent> SaveInventoryCountAsync(SaveInventoryCountRequest request)
        {
            if (request == null || request.InventoryCount == null)
                return WebResponseContent.Instance.Error("参数不正确");

            // 要求必须选择仓库
            if (!request.InventoryCount.WarehouseId.HasValue)
                return WebResponseContent.Instance.Error("请先选择仓库");

            try
            {
                // 生成盘点单号（如果前端未传）
                if (string.IsNullOrEmpty(request.InventoryCount.CountCode))
                {
                    request.InventoryCount.CountCode = $"IC{DateTime.Now:yyyyMMddHHmmss}";
                }

                // 记录请求中的主表CountStatus值
                Console.WriteLine($"请求主表CountStatus: '{request.InventoryCount.CountStatus}', 类型: {request.InventoryCount.CountStatus?.GetType().Name ?? "null"}");
                
                // 处理主表CountStatus，确保符合数据库长度限制(nvarchar(3))
                string processedCountStatus = null;
                if (!string.IsNullOrEmpty(request.InventoryCount.CountStatus))
                {
                    // 如果有值，截取前3个字符以符合数据库限制
                    processedCountStatus = request.InventoryCount.CountStatus.Substring(0, Math.Min(3, request.InventoryCount.CountStatus.Length));
                }
                // 安全检查：确保最终保存的CountStatus不超过3个字符
                if (processedCountStatus != null && processedCountStatus.Length > 3)
                {
                    processedCountStatus = processedCountStatus.Substring(0, 3);
                }
                
                // 记录处理后的主表CountStatus值
                Console.WriteLine($"处理后主表CountStatus: '{processedCountStatus}', 长度: {processedCountStatus?.Length ?? 0}");
                
                // 保存主表
                var main = new InventoryCount
                {
                    CountCode = request.InventoryCount.CountCode,
                    CountType = request.InventoryCount.CountType,
                    StartTime = request.InventoryCount.StartTime,
                    EndTime = request.InventoryCount.EndTime,
                    WarehouseId = request.InventoryCount.WarehouseId,
                    CreatorId = request.InventoryCount.CreatorId,
                    HandlerId = request.InventoryCount.HandlerId,
                    Department = request.InventoryCount.Department,
                    CreateTime = request.InventoryCount.CreateTime ?? DateTime.Now,
                    CountStatus = processedCountStatus, // 使用处理后的值
                    Remark = request.InventoryCount.Remark
                };

                // 使用 ServiceBase 提供的 AddEntity 将主表保存
                var addMain = AddEntity(main, false);
                if (!addMain.Status)
                {
                    return addMain;
                }

                // 处理明细
                var itemService = AutofacContainerModule.GetService<IInventoryCountItemService>();
                if (request.CountItems != null && request.CountItems.Count > 0)
                {
                    // 在事务中处理明细
                    await repository.DbContext.Ado.BeginTranAsync();
                    try
                    {
                        // 先删除旧的（如果有）
                        await itemService.DeleteItemsByCountCodeAsync(request.InventoryCount.CountCode);

                        var items = new List<InventoryCountItem>();
                        foreach (var dto in request.CountItems)
                        {
                            var item = new InventoryCountItem
                            {
                                CountCode = request.InventoryCount.CountCode,
                                ProductId = dto.ProductId ?? 0,
                                ProductCode = dto.ProductCode,
                                ProductName = dto.ProductName,
                                Spec = dto.Spec,
                                Unit = dto.Unit,
                                BookStock = dto.BookStock,
                                BookAmount = dto.BookAmount,
                                CountLocation = dto.CountLocation,
                                CountQuantity = dto.CountQuantity,
                                ReferencePrice = dto.ReferencePrice,
                                Remark = dto.Remark
                            };

                            // 计算盈亏
                            item.ProfitLossQuantity = (item.CountQuantity ?? 0) - (item.BookStock ?? 0);
                            item.ProfitLossAmount = (item.ProfitLossQuantity ?? 0) * (item.ReferencePrice ?? 0);
                            // 设置CountStatus值以匹配数据库enum类型定义
                            if (item.ProfitLossQuantity > 0)
                                item.CountStatus = "盘盈"; // 匹配数据库enum值
                            else if (item.ProfitLossQuantity < 0)
                                item.CountStatus = "盘亏"; // 匹配数据库enum值
                            else
                                item.CountStatus = "无盈亏"; // 匹配数据库enum值

                            items.Add(item);
                        }

                        // 调用新增的明细服务方法
                        await itemService.AddItemsAsync(items);
                        await repository.DbContext.Ado.CommitTranAsync();
                    }
                    catch (Exception ex)
                    {
                        await repository.DbContext.Ado.RollbackTranAsync();
                        // 记录详细错误信息
                        Console.WriteLine($"保存盘点明细时发生错误: {ex.Message}");
                        Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                        throw ex;
                    }
                }

                return WebResponseContent.Instance.OK("保存成功", new { CountCode = request.InventoryCount.CountCode });
            }
            catch (Exception ex)
            {
                // 记录详细的异常信息
                Console.WriteLine($"保存盘点单失败: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                return WebResponseContent.Instance.Error($"保存失败：{ex.Message}");
            }
        }

        // 新增构造函数，确保 repository 被注入并赋值
        public InventoryCountService(IInventoryCountRepository repository) : base(repository)
        {
            // 使用基类构造函数初始化Response和repository
        }

        // 方法开始处加入 repository 空检查
        public WebResponseContent InitializeCheck()
        {
            if (repository == null)
            {
                // 更明确的错误信息，便于定位 DI 注入问题
                return WebResponseContent.Instance.Error("服务初始化失败：IInventoryCountRepository 未注入（repository 为 null）。请检查 DI 注册与 ServiceBase 构造。");
            }

            return null;
        }
    }
}
